package fr.greta.centre.dao;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import javax.naming.NamingException;

import fr.greta.centre.metier.Candidat;
import fr.greta.centre.metier.Candidature;
import fr.greta.centre.metier.Etat;
import fr.greta.centre.metier.Promotion;
import fr.greta.centre.metier.StagiaireEtPromo;

public class CandidatureDAOImpl implements CandidatureDAO {
	
	public final static int ETAT_INSCRIT = 7;
	/*
	 * public static void main(String[] args) { CandidatureDAOImpl dao = new
	 * CandidatureDAOImpl(); ArrayList<Candidature> lesCandidatures =
	 * dao.findByIdPersonne(1); System.out.println(lesCandidatures.size()); }
	 */
	public void inserer(Candidat candidat, Candidature candidature) throws SQLException {
		// Recuperer une connexion
		Connection connexion;
		try {
			connexion = Bd.getConnect();
			try {
				connexion.setAutoCommit(false);
				// Inserer le candidat avec cette connexion
				insererCandidat(candidat, connexion);// une mise a� jour du
														// candidat puisqu'il
														// existe
				// Inserer la candidature avec la meme connexion
				insererCandidature(candidature, connexion);
				// Valider la transaction
				connexion.commit();
				// Annuler la transaction (les deux actions sont annullees)
				connexion.rollback();
			}
			catch (SQLException exc) {
				// Annuler la transaction (les deux actions sont annullees)
				connexion.rollback();
				throw exc;
			}
		}
		catch (NamingException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}

	private void insererCandidature(Candidature candidature, Connection connexion)
			throws SQLException {
		save(candidature, connexion);
	}

	public void save(Candidature candidature, Connection connexion) throws SQLException {
		String sql = "INSERT INTO candidature (id_candidat, id_promotion, etat_candidature)"
				+ " VALUES(?, ?, ?)";
		PreparedStatement st;
		try {
			st = connexion.prepareStatement(sql);
			st.setInt(1, candidature.getCandidat().getId());
			st.setInt(2, candidature.getPromotion().getIdPromotion());
			st.setInt(3, candidature.getEtat().getIdEtat());
			st.executeUpdate();
		}
		catch (SQLException e) {
			e.printStackTrace();
			throw e;
		}
	}

	private void insererCandidat(Candidat candidat, Connection connexion) throws SQLException {
		CandidatDAOImpl dao = new CandidatDAOImpl();
		dao.save(candidat, connexion);
	}

	/** Sauver candidature pour un candidat existant */
	@Override
	public int save(Candidature candidature) throws SQLException {
		{
			throw new SQLException("Not yet implemented");
		}
	}

	/*
	 * public int saveSiCandidatConnu(Candidature candidature) throws
	 * SQLException { Connection connexion = Bd.getConnect(); // En faire une
	 * transaction connexion.setAutoCommit(false); try {
	 * saveSansTransaction(candidature, connexion); CandidatDAO dao = new
	 * CandidatDAOImpl(); dao.saveSansTransaction(candidature.getCandidat(),
	 * connexion); connexion.commit(); } catch (SQLException exc) {
	 * connexion.rollback(); throw exc; } return 0; }
	 */
	public int saveSansTransaction(Candidature t, Connection connexion) throws SQLException {
		String sql = "INSERT INTO candidature (id_candidat, id_promotion, etat_candidature)"
				+ " VALUES(?, ?, ?)";
		PreparedStatement st = connexion.prepareStatement(sql);
		st.setInt(1, t.getCandidat().getId());
		st.setInt(2, t.getPromotion().getIdPromotion());
		st.setInt(3, t.getEtat().getIdEtat());
		return st.executeUpdate();
	}

	/** Sauver candidature + candidat */
	@Override
	public int saveCandidatNouveau(Candidature candidature) throws SQLException {
		assert candidature.getCandidat() != null;
		Connection connection;
		try {
			connection = Bd.getConnect();
			// On fait une transaction
			connection.setAutoCommit(false);
			// Inserer le candidat et la candidature en 1 transaction
			try {
				CandidatDAO dao = new CandidatDAOImpl();
				dao.save(candidature.getCandidat());
				save(candidature);
				connection.commit();
				return 0;
			}
			catch (SQLException exc) {
				System.out.println(exc.getMessage());
				connection.rollback();
				throw exc;
			}
		}
		catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return 1;
	}

	@Override
	public boolean delete(int id_candidat, int idPromotion) {
		String sql = "DELETE FROM candidature WHERE id_candidat = ?, AND id_promotion = ?,";
		PreparedStatement st;
		try {
			st = Bd.getConnect().prepareStatement(sql);
			st.setInt(1, id_candidat);
			st.setInt(2, idPromotion);
			return st.execute();
		}
		catch (SQLException e) {
			e.printStackTrace();
		}
		catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}

	public Candidature findByKey(int id_candidat) throws SQLException {
		try {
			Connection conn = Bd.getConnect();
			Statement st = conn.createStatement();
			String sql = "SELECT id_candidat"
					+ "FROM candidat INNER JOIN candidature ON candidat.id_candidat = candidature.id_candidat "
					+ "WHERE id_candidat =" + id_candidat;
			ResultSet rs = st.executeQuery(sql);
			if (rs.next()) {
				// @SuppressWarnings("unchecked")
				List<Candidature> lesCandidatures = (List<Candidature>) new CandidatDAOImpl()
						.findByKey(rs.getInt("candidat.id_candidat"));
				rs = (ResultSet) new Candidature();
			}
		}
		catch (SQLException e) {
			throw e;
		}
		catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	public List<Candidature> findAll() throws SQLException {
		List<Candidature> lesCandidatures = new ArrayList<Candidature>();
		try {
			ResultSet resultat;
			Connection connect = Bd.getConnect();
			Statement st = connect.createStatement();
			// connect.setAutoCommit(false);
			String sql = "SELECT * FROM candidature ";
			resultat = st.executeQuery(sql);
			while (resultat.next()) {
				Candidat unCandidat = new CandidatDAOImpl().findByKey(resultat
						.getInt("id_candidat"));
				Promotion unePromotion = new Promotion();
				unePromotion.setIdPromotion(resultat.getInt("id_promotion"));
				Etat unEtat = new EtatDAOImpl().findByKey(resultat.getInt("etat_candidature"));
				Candidature uneCandidature = new Candidature();
				uneCandidature.setCandidat(unCandidat);
				uneCandidature.setEtat(unEtat);
				uneCandidature.setPromotion(unePromotion);
				lesCandidatures.add(uneCandidature);
			}
		}
		catch (SQLException e) {
			e.printStackTrace();
		}
		catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return lesCandidatures;
	}

	@Override
	public ArrayList<Candidature> findByIdPersonne(int idPersonne) {
		ArrayList<Candidature> lesCandidatures = new ArrayList<Candidature>();
		try {
			Statement st = Bd.getConnect().createStatement();
			String sql = "SELECT * FROM candidature" + " WHERE id_candidat = " + idPersonne;
			ResultSet rs = st.executeQuery(sql);
			CandidatDAOImpl candidatDAO = new CandidatDAOImpl();
			Candidat leCandidat = candidatDAO.findByKey(idPersonne);
			while (rs.next()) {
				PromotionDAOImpl unePromotionDAO = new PromotionDAOImpl();
				Promotion unePromotion = unePromotionDAO.findByKey(rs.getInt("id_promotion"));
				EtatDAOImpl etatDAO = new EtatDAOImpl();
				Etat unEtat = etatDAO.findByKey(rs.getInt("etat_candidature"));
				Candidature uneCandidature = new Candidature(leCandidat, unePromotion, unEtat);
				lesCandidatures.add(uneCandidature);
			}
		}
		catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return lesCandidatures;
	}

	public List<Candidature> findByIdPromotion(int idPromotion) {
		ArrayList<Candidature> lesCandidatures = new ArrayList<Candidature>();
		String sql = "SELECT * FROM candidature WHERE id_promotion = ?";
		try {
			PreparedStatement st = Bd.getConnect().prepareStatement(sql);
			st.setInt(1, idPromotion);
			ResultSet rs = st.executeQuery();
			while (rs.next()) {
				Candidat unCandidat = new CandidatDAOImpl().findByKey(rs.getInt("id_candidat"));
				Promotion unePromotion = new PromotionDAOImpl().findByKey(idPromotion);
				Etat unEtat = new EtatDAOImpl().findByKey(rs.getInt("etat_candidature"));
				Candidature uneCandidature = new Candidature(unCandidat, unePromotion, unEtat);
				lesCandidatures.add(uneCandidature);
			}
			return lesCandidatures;
		}
		catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	public List<StagiaireEtPromo> getStagiairesByIdPromotion(int idPromotion) {
		List<StagiaireEtPromo> stagiaires = new ArrayList<StagiaireEtPromo>();
		String sql = "select * from candidature "
				+ "inner join candidat on candidature.id_candidat = candidat.id_candidat "
				+ "where id_promotion = " + idPromotion + " and etat_candidature = " + ETAT_INSCRIT;
		System.out.println(sql);
		StagiaireEtPromo stagiaire;
		try {
			PreparedStatement st = Bd.getConnect().prepareStatement(sql);
			//st.setInt(1, idPromotion);
			ResultSet rs = st.executeQuery();
			while (rs.next()) {
				stagiaire = new StagiaireEtPromo();
				stagiaire.setIdPromotion(rs.getInt("id_promotion"));
				stagiaire.setNom(rs.getString("nom"));
				stagiaire.setPrenom(rs.getString("prenom"));
				stagiaire.setAdresse(rs.getString("adresse"));
				stagiaire.setCp(rs.getString("cp"));
				stagiaire.setVille(rs.getString("ville"));
				stagiaires.add(stagiaire);
			}
		}
		catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (NamingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return stagiaires;
	}
  public int updatePromoCandidature(int idCandidat, int idNouvellePromo,
			int idPromoActuelle) throws SQLException {
		
		
		try {
				String sql = "UPDATE centre_formation.candidature SET id_promotion=? WHERE id_candidat=? AND id_promotion=?";

				Connection conn = Bd.getConnect();

				PreparedStatement st = conn.prepareStatement(sql);

				st.setInt(1, idNouvellePromo);
				st.setInt(2, idCandidat);
				st.setInt(3, idPromoActuelle);
				

				st.executeUpdate();

				return 1;
			}
			catch (SQLException e) {
				System.out.println(e.getMessage());
				throw e;
			}
	}

	@Override
	public boolean delete(int id) throws SQLException {
		// TODO Auto-generated method stub
		return false;
	}
	/*
	 * @Override public void mettreAjour(Candidat candidat, Candidature
	 * candidature) throws SQLException { // Recuperer une connexion Connection
	 * connexion; try { connexion = Bd.getConnect(); // En faire une transaction
	 * connexion.setAutoCommit(false); try { // Inserer le candidat avec cette
	 * connexion mettreAjourCandidat(candidat, connexion);// une mise à jour du
	 * candidat puisqu'il existe // Inserer la candidature avec la meme
	 * connexion insererCandidature(candidature, connexion); // Valider la
	 * transaction connexion.commit(); } catch (SQLException exc) { // Annuler
	 * la transaction (les deux actions sont annullees) connexion.rollback();
	 * throw exc; } } catch (NamingException e) { // TODO Auto-generated catch
	 * block e.printStackTrace(); }
	 * 
	 * 
	 * }
	 * 
	 * 
	 * private void mettreAjourCandidat(Candidat candidat, Connection connexion)
	 * throws SQLException{ CandidatDAOImpl daoImpl = new CandidatDAOImpl();
	 * daoImpl.mettreAjour(candidat, connexion);
	 * 
	 * }
	 */
}
